﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp1.Base
{

    /*
     
     原理
      文本框 password和 拓展附加绑定
      拓展附加和视图模型绑定

     
     */

    /// <summary>
    /// PasswordBox属性
    /// </summary>
    class PasswordBoxExtend
    {

        //附加属性(特殊的依赖属性)
        //propa 按拉你改下tab键
        /// <summary>
        /// 自定义属性名
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetMyPassword(DependencyObject obj)
        {
            return (string)obj.GetValue(MyPasswordProperty);
        }

        /// <summary>
        /// 属性赋值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        public static void SetMyPassword(DependencyObject obj, string value)
        {
            obj.SetValue(MyPasswordProperty, value);
        }
        /// <summary>
        /// 注册属性
        /// </summary>
        // Using a DependencyProperty as the backing store for MyPassword.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPasswordProperty =
            DependencyProperty.RegisterAttached("MyPassword", typeof(string), typeof(PasswordBoxExtend), 
                new PropertyMetadata("",OnMyPwdChanged));//alt+enter 生成方法

        /// <summary>
        /// MyPwd->Password,MyPwd值改变，给Password属性赋值
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private static void OnMyPwdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = d as PasswordBox;
            if (passwordBox != null) 
            {
                passwordBox.Password = (string)e.NewValue;//值改变时，给Password赋值
            }
            SetSelection(passwordBox, passwordBox.Password.Length, 0);
        }
        /// <summary>
        /// 设置光标位置
        /// </summary>
        /// <param name="passwordBox"></param>
        /// <param name="start">光标开始位置</param>
        /// <param name="length">选中长度</param>
        private static void SetSelection(PasswordBox passwordBox, int start, int length)
        {
            passwordBox.GetType()
                       .GetMethod("Select", BindingFlags.Instance | BindingFlags.NonPublic)
                       .Invoke(passwordBox, new object[] { start, length
         });
        }


        //Password发生变化,通知MyPasswod改变
        //1如何知道Password改变
        //2通知Mypassword改变



        public static bool GetIsBInd(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsBIndProperty);
        }

        public static void SetIsBInd(DependencyObject obj, bool value)
        {
            obj.SetValue(IsBIndProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsBInd.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsBIndProperty =
            DependencyProperty.RegisterAttached("IsBInd", typeof(bool), typeof(PasswordBoxExtend), 
                new PropertyMetadata(false,OnPropChanged));

        private static void OnPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = d as PasswordBox;
            if (passwordBox != null)
            {
                //1 如果通知password属性变化了，则通知MyPassword改变

                //如果通知password属性没变化，则不通知MyPassword改变

                if ((bool)e.NewValue) //如果为新值，已经改变了
                {
                    passwordBox.PasswordChanged += OnMyPwdChanged;
                }

                if ((bool)e.OldValue) //如果为旧值，就没变了
                {
                    passwordBox.PasswordChanged -= OnMyPwdChanged;
                }
            }
        }

        private static void OnMyPwdChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;
            if (passwordBox != null)
            {
                SetMyPassword(passwordBox, passwordBox.Password);
            }
        }


    }
}
